using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;
using ICSharpCode.TextEditor;
using ICSharpCode.TextEditor.Gui.CompletionWindow;
using ICSharpCode.TextEditor.Document;
using ICSharpCode.TextEditor.Actions;

using ICSharpCode.XmlEditor;
using System.Xml;
using System.IO;

namespace SPCAMLEditor
{
    public partial class TextEditor : UserControl
    {
         protected ICSharpCode.XmlEditor.XmlEditorControl xmlEditorControl;

        public TextEditor()
        {
            InitializeComponent();

            xmlEditorControl = new XmlEditorControl();

            xmlEditorControl.Document.HighlightingStrategy = HighlightingStrategyFactory.CreateHighlightingStrategy("XML");

            xmlEditorControl.Dock = DockStyle.Fill;

            this.Controls.Add(xmlEditorControl);
            xmlEditorControl.Encoding = System.Text.Encoding.Default;

            string schemaFile = Environment.CurrentDirectory + "\\CAMLSchema.xsd";
            SetSchemaFile(schemaFile);

            //SetSchema();
            this.xmlEditorControl.ShowEOLMarkers = true;
            this.xmlEditorControl.ShowSpaces = true;
            this.xmlEditorControl.ShowTabs = true;
            this.xmlEditorControl.ShowVRuler = true;
            this.xmlEditorControl.DefaultNamespacePrefix = "";
            //  this.xmlEditor.DefaultSchemaCompletionData = null;

            this.xmlEditorControl.IndentStyle = IndentStyle.Auto;            
          //  this.xmlEditor.ActiveTextAreaControl.Caret.PositionChanged += new EventHandler(this.CaretChanged);
          //  this.xmlEditor.ActiveTextAreaControl.Caret.CaretModeChanged += new EventHandler(this.CaretModeChanged);
           // this.xmlEditor.Font = new Font("Lucida Console", 9f);
            //this.xmlEditor.ShowEOLMarkers = false;
            //this.xmlEditor.ShowHRuler = false;
            //this.xmlEditor.ShowInvalidLines = false;
            //this.xmlEditor.ShowSpaces = false;
            //this.xmlEditor.ShowTabs = false;
            //this.xmlEditor.ShowVRuler = false;

            //this.xmlEditorControl.LostFocus += new EventHandler(xmlEditorControl_LostFocus);
            this.xmlEditorControl.Document.DocumentChanged += new DocumentEventHandler(Document_DocumentChanged);

            this.Controls.Add(this.xmlEditorControl);
        }

        public void SetSchema()
        { 
            //string schemaFile = Environment.CurrentDirectory + "\\CoreDefinitions.xsd";
            string schemaFile1 = Environment.CurrentDirectory + "\\CamlView.xsd";
            // string schemaFile2 = Environment.CurrentDirectory + "\\CamlQuery.xsd";           

            //  schemaFile1 = @"C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\TEMPLATE\XML\CamlView.xsd";

            XmlSchemaCompletionData xmlSchemaCompletionData = new XmlSchemaCompletionData(schemaFile1);
            this.xmlEditorControl.SchemaCompletionDataItems = new XmlSchemaCompletionDataCollection();


            // this.xmlEditor.SchemaCompletionDataItems.Add(new XmlSchemaCompletionData(schemaFile));
            this.xmlEditorControl.SchemaCompletionDataItems.Add(xmlSchemaCompletionData);
            // this.xmlEditor.SchemaCompletionDataItems.Add(new XmlSchemaCompletionData(schemaFile2));

            this.xmlEditorControl.DefaultNamespacePrefix = "";
            this.xmlEditorControl.DefaultSchemaCompletionData = xmlSchemaCompletionData;
            this.xmlEditorControl.EnableFolding = true;
        }

        public void SetSchemaFile(string fileName)
        {
            if (!File.Exists(fileName))
            {
                MessageBox.Show("Can not load schema :" + fileName);
                return;
            }

            XmlSchemaCompletionData xmlSchemaCompletionData = new XmlSchemaCompletionData(fileName);
            this.xmlEditorControl.SchemaCompletionDataItems = new XmlSchemaCompletionDataCollection();
            this.xmlEditorControl.SchemaCompletionDataItems.Add(xmlSchemaCompletionData);
            this.xmlEditorControl.DefaultNamespacePrefix = "";
            this.xmlEditorControl.DefaultSchemaCompletionData = xmlSchemaCompletionData;
            this.xmlEditorControl.EnableFolding = true;
        }

        private string FormatXml(string source)
        {
            StringBuilder sb = new StringBuilder();
            XmlTextWriter writer = null;

            try
            {
                XmlDocument doc = new XmlDocument();
                doc.LoadXml(source);

                writer = new XmlTextWriter(new StringWriter(sb));
                writer.Formatting = Formatting.Indented;
                doc.WriteTo(writer);
            }
            catch
            {
                return source;
            }
            finally
            {
                if (writer != null) writer.Close();
            }

            return sb.ToString();
        }

        private bool _IsTextChanged = false;
        public bool IsTextChanged
        {
            get
            {
                return _IsTextChanged ;               
            }
        }

        private bool _TextSettedEventDisabled  = false  ;

        public void  DisableTextSettedEventFired()
        {
            _TextSettedEventDisabled = true;
        }

        public void EnableTextSettedEventFired()
        {
            _TextSettedEventDisabled = false ;
        }

        public new string Text
        {
            get 
            {
                return this.xmlEditorControl.Text;
            }
            set 
            {
                this.xmlEditorControl.Document.DocumentChanged -= new DocumentEventHandler(Document_DocumentChanged);

                if (string.IsNullOrEmpty(value))
                    this.xmlEditorControl.Text = "";
                else
                    this.xmlEditorControl.Text = this.FormatXml( value );

                this.xmlEditorControl.Refresh();
                this.xmlEditorControl.Document.FoldingManager.UpdateFoldings(string.Empty, null);

                this.xmlEditorControl.Document.DocumentChanged += new DocumentEventHandler(Document_DocumentChanged);
                _IsTextChanged = false;

                if (  !_TextSettedEventDisabled && this.TextSetted != null)
                    TextSetted(this, EventArgs.Empty);
            }
        }

        void Document_DocumentChanged(object sender, DocumentEventArgs e)
        {
            if (e.Text == "\r\n") return;

            this._IsTextChanged = true;

            if (XmlNodeChanged == null) return;

            try
            {
                XmlDocument xml = new XmlDocument();
                xml.LoadXml(this.Text);
            }
            catch
            {
                return;
            }

            
            XmlNodeChanged(this, EventArgs.Empty);
        }

        public event EventHandler XmlNodeChanged;

        public event EventHandler TextSetted;

    }
}
